package com.shaozi.nc.configuration;

import java.text.DateFormat;
import java.text.SimpleDateFormat;

import org.apache.log4j.Logger;
import org.quartz.Trigger;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import com.shaozi.nc.quartz.attendance.AttendanceSignRuleJobExecute;
import com.shaozi.nc.quartz.attendance.ComplainEndDateRuleJobExecute;
import com.shaozi.nc.quartz.crm.CrmSaleOpenSeeRecoverExecute;
import com.shaozi.nc.quartz.crm.CrmSaleQuiteOpenSeeExecute;
import com.shaozi.nc.quartz.workreport.ReportRuleJobExecute;

@Configuration
public class QuartzConfiguration {

	private Logger logger = Logger.getLogger(QuartzConfiguration.class);

	@Value("${cron.expression.attendance}")
	private String attendanceCronExpression;
	@Value("${cron.expression.attendance.complain}")
	private String attendanceComplainCronExpression;
	@Value("${cron.expression.report}")
	private String reportCronExpression;

	@Value("${cron.expression.crm.sale.open}")
	private String crmSaleOpenCronExpression;
	@Value("${cron.expression.crm.sale.quite}")
	private String crmSaleQuiteCronExpression;

	@Value("${attendance.ignore.data.init}")
	private boolean ignoreDataInit;

	public QuartzConfiguration() {
		super();
	}

	/************************ attendanceSign *********************/
	@Bean
	public AttendanceSignRuleJobExecute attendanceSignRuleJobExecute() {
		AttendanceSignRuleJobExecute attendanceSignRuleJobExecute = new AttendanceSignRuleJobExecute();
		attendanceSignRuleJobExecute.setIgnoreDataInit(ignoreDataInit);
		return attendanceSignRuleJobExecute;
	}

	// 配置中设定了
	// ① targetMethod: 指定需要定时执行JobExecute中的execute()方法
	// ② concurrent：对于相同的JobDetail，当指定多个Trigger时, 很可能第一个job完成之前，
	// 第二个job就开始了。指定concurrent设为false，多个job不会并发运行，第二个job将不会在第一个job完成之前开始。
	// ③ cronExpression：0/10 * * * * ?表示每10秒执行一次，具体可参考附表。
	// ④ triggers：通过再添加其他的ref元素可在list中放置多个触发器。
	// scheduleInfoAction中的simpleJobTest()方法
	@Bean(name = "attendanceSignJobDetailFactoryBean")
	public MethodInvokingJobDetailFactoryBean attendanceSignJobDetailFactoryBean(
			AttendanceSignRuleJobExecute attendanceSignRuleJobExecute) {
		MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean();
		bean.setTargetObject(attendanceSignRuleJobExecute);
		bean.setTargetMethod("execute");
		// 将并发设置为false
		bean.setConcurrent(false);
		return bean;
	}

	@Bean(name = "attendanceSignTriggerFactoryBean")
	public CronTriggerFactoryBean attendanceSignTriggerFactoryBean(
			@Qualifier("attendanceSignJobDetailFactoryBean") MethodInvokingJobDetailFactoryBean attendanceSignJobDetailFactoryBean) {
		CronTriggerFactoryBean tigger = new CronTriggerFactoryBean();
		tigger.setJobDetail(attendanceSignJobDetailFactoryBean.getObject());
		tigger.setCronExpression(attendanceCronExpression);
		return tigger;
	}

	/************************ complainEndDateTrigger *********************/
	@Bean
	public ComplainEndDateRuleJobExecute complainEndDateRuleJobExecute() {
		return new ComplainEndDateRuleJobExecute();
	}

	@Bean(name = "complainEndDateJobDetailFactoryBean")
	public MethodInvokingJobDetailFactoryBean complainEndDateJobDetailFactoryBean(
			ComplainEndDateRuleJobExecute complainEndDateTriggerFactoryBean) {
		MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean();
		bean.setTargetObject(complainEndDateTriggerFactoryBean);
		bean.setTargetMethod("execute");
		// 将并发设置为false
		bean.setConcurrent(false);
		return bean;
	}

	@Bean(name = "complainEndDateTriggerFactoryBean")
	public CronTriggerFactoryBean complainEndDateTriggerFactoryBean(
			@Qualifier("complainEndDateJobDetailFactoryBean") MethodInvokingJobDetailFactoryBean complainEndDateJobDetailFactoryBean) {
		CronTriggerFactoryBean tigger = new CronTriggerFactoryBean();
		tigger.setJobDetail(complainEndDateJobDetailFactoryBean.getObject());
		tigger.setCronExpression(attendanceComplainCronExpression);
		return tigger;
	}

	/************************ reportRuleTrigger *********************/
	@Bean
	public ReportRuleJobExecute reportRuleJobExecute() {
		return new ReportRuleJobExecute();
	}

	@Bean(name = "reportRuleJobDetailFactoryBean")
	public MethodInvokingJobDetailFactoryBean reportRuleJobDetailFactoryBean(
			ReportRuleJobExecute reportRuleJobExecute) {
		MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean();
		bean.setTargetObject(reportRuleJobExecute);
		bean.setTargetMethod("execute");
		// 将并发设置为false
		bean.setConcurrent(false);
		return bean;
	}

	@Bean(name = "reportRuleTriggerFactoryBean")
	public CronTriggerFactoryBean reportRuleTriggerFactoryBean(
			@Qualifier("reportRuleJobDetailFactoryBean") MethodInvokingJobDetailFactoryBean reportRuleJobDetailFactoryBean) {
		CronTriggerFactoryBean tigger = new CronTriggerFactoryBean();
		tigger.setJobDetail(reportRuleJobDetailFactoryBean.getObject());
		tigger.setCronExpression(reportCronExpression);
		return tigger;
	}

	/***** CRM回收预提醒 crmSaleOpenSeeRecoverTrigger ******/
	@Bean
	public CrmSaleOpenSeeRecoverExecute crmSaleOpenSeeRecoverExecute() {
		return new CrmSaleOpenSeeRecoverExecute();
	}

	@Bean(name = "crmSaleOpenSeeRecoverJobDetailFactoryBean")
	public MethodInvokingJobDetailFactoryBean crmSaleOpenSeeRecoverJobDetailFactoryBean(
			CrmSaleOpenSeeRecoverExecute crmSaleOpenSeeRecoverExecute) {
		MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean();
		bean.setTargetObject(crmSaleOpenSeeRecoverExecute);
		bean.setTargetMethod("execute");
		// 将并发设置为false
		bean.setConcurrent(false);
		return bean;
	}

	@Bean(name = "crmSaleOpenSeeRecoverTriggerFactoryBean")
	public CronTriggerFactoryBean crmSaleOpenSeeRecoverTriggerFactoryBean(
			@Qualifier("crmSaleOpenSeeRecoverJobDetailFactoryBean") MethodInvokingJobDetailFactoryBean crmSaleOpenSeeRecoverJobDetailFactoryBean) {
		CronTriggerFactoryBean tigger = new CronTriggerFactoryBean();
		tigger.setJobDetail(crmSaleOpenSeeRecoverJobDetailFactoryBean.getObject());
		tigger.setCronExpression(crmSaleOpenCronExpression);
		return tigger;
	}

	/***** CRM退回提醒 crmSaleQuiteOpenSeeTrigger ******/
	@Bean
	public CrmSaleQuiteOpenSeeExecute crmSaleQuiteOpenSeeExecute() {
		return new CrmSaleQuiteOpenSeeExecute();
	}

	@Bean(name = "crmSaleQuiteOpenSeeJobDetailFactoryBean")
	public MethodInvokingJobDetailFactoryBean crmSaleQuiteOpenSeeJobDetailFactoryBean(
			CrmSaleQuiteOpenSeeExecute crmSaleQuiteOpenSeeExecute) {
		MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean();
		bean.setTargetObject(crmSaleQuiteOpenSeeExecute);
		bean.setTargetMethod("execute");
		// 将并发设置为false
		bean.setConcurrent(false);
		return bean;
	}

	@Bean(name = "crmSaleQuiteOpenSeeTriggerFactoryBean")
	public CronTriggerFactoryBean crmSaleQuiteOpenSeeTriggerFactoryBean(
			@Qualifier("crmSaleQuiteOpenSeeJobDetailFactoryBean") MethodInvokingJobDetailFactoryBean crmSaleQuiteOpenSeeJobDetailFactoryBean) {
		CronTriggerFactoryBean tigger = new CronTriggerFactoryBean();
		tigger.setJobDetail(crmSaleQuiteOpenSeeJobDetailFactoryBean.getObject());
		tigger.setCronExpression(crmSaleQuiteCronExpression);
		return tigger;
	}

	@Bean
	public SchedulerFactoryBean schedulerFactoryByCron(CronTriggerFactoryBean[] triggerFactoryBean) {
		if (triggerFactoryBean.length == 0)
			return null;
		SchedulerFactoryBean bean = new SchedulerFactoryBean();

		Trigger[] triggers = new Trigger[triggerFactoryBean.length];
		for (int i = 0; i < triggerFactoryBean.length; i++) {
			triggers[i] = triggerFactoryBean[i].getObject();
			// Date fireTime = triggers[i].getNextFireTime();
			// if (fireTime == null) {
			// logger.warn(triggers[i].getJobKey() + " not fired");
			// } else {
			// logger.info(triggers[i].getJobKey() + " fired at : " +
			// df.format(fireTime));
			// }
		}
		bean.setTriggers(triggers);
		return bean;
	}

}
